package
{
	import flash.display.DisplayObject;
	import flash.utils.*;
	import flash.utils.setTimeout;
	import flash.utils.clearTimeout;
	//import com.greensock.TweenLite;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.display.Sprite;
	public class MyList extends Sprite
	{
		private var theMask:Bitmap;
		private var bg:Sprite;
		public var container:Sprite;
		public function set MaskRect(rect:Rectangle):void
		{
			theMask.width = Math.abs(rect.right - rect.left);
			theMask.height= Math.abs(rect.bottom - rect.top);
			theMask.x= rect.left;
			theMask.y= rect.top;
			container.mask = theMask;
		}
		public var onUpdate:Function = null;

		private var rollRect:Rectangle;
		private var isVRoll:Boolean = true;
		public function setVRoll(b:Boolean):void
		{
			isVRoll =b;
		}

		public function MyList ()
		{
			if(bg== null){
				bg = new Sprite();
				bg.addChild(new Bitmap(new BitmapData(20,20)));
				bg.mouseChildren = false;
			}
			container = new Sprite();
			theMask = new Bitmap(new BitmapData(2,2));
			addChild(container);
			addChild(theMask);
			addEventListener(MouseEvent.MOUSE_DOWN,drags);
		}

		private var moveStartTime:int;
		private var moveStartPos:int;
		private function drags(e:MouseEvent):void
		{
			initBg();
			switch(e.type)
			{
				case MouseEvent.MOUSE_DOWN:
					TweenLite.killTweensOf(container);
					moveStartTime = getTimer();
					if(isVRoll) moveStartPos = container.y;
					else moveStartPos = container.x;
					stage.addEventListener(MouseEvent.MOUSE_UP,drags);
					if(stage)stage.removeEventListener(MouseEvent.MOUSE_MOVE,drags);
					/*container.addEventListener(MouseEvent.MOUSE_OUT,drags);*/
					if(isVRoll)container.startDrag(false,new Rectangle(theMask.x,theMask.y+theMask.height,0,-theMask.height-container.height));
					else container.startDrag(false,new Rectangle(theMask.x+theMask.width,theMask.y,-theMask.width-container.width,0));
					break;
				case MouseEvent.MOUSE_MOVE:
					if(onUpdate!=null)
					{
						onUpdate();
					}
					break;
				case MouseEvent.MOUSE_OUT:
					if(e.currentTarget!=this)
					{
						break;
					}
				case MouseEvent.MOUSE_UP:
					if(stage)stage.removeEventListener(MouseEvent.MOUSE_MOVE,drags);
					if(stage)stage.removeEventListener(MouseEvent.MOUSE_UP,drags);
					/*container.removeEventListener(MouseEvent.MOUSE_OUT,drags);*/
					container.stopDrag();
					clearTimeout(timeoutId);
					if(can_back){
						/*
						   timeoutId = setTimeout(backtoShow,100);
						 */
						var moveY:int = container.x - moveStartPos;
						if(isVRoll) moveY = container.y - moveStartPos;
						var deltaTime:int = getTimer() - moveStartTime;
						var speed:Number = moveY*1000.0/deltaTime;//s
						var _time:Number = Math.abs(speed/1000);//s
						var targetY:int = container.y + _time*speed;//s
						var targetX:int = container.x + _time*speed;//s
						//var theMask:DisplayObject = container.mask;
						if(isVRoll){
							if(container.height<theMask.height){
								targetY = theMask.y;
								_time = Math.max(.1,Math.abs(targetY-container.y)/10000);
							}else if(targetY>theMask.y){
								if(targetY>theMask.y + theMask.height/10)
									targetY = theMask.y + theMask.height/10;
								_time = Math.max(.1,Math.abs(targetY-container.y)/10000);
							}else if(container.height > theMask.height && targetY+container.height < theMask.y + theMask.height){
								targetY = theMask.y + theMask.height - container.height;
								_time = Math.max(.1,Math.abs(targetY-container.y)/10000);
							}
						}else{
							if(targetX>theMask.x){
								if(targetX > theMask.x + theMask.width/10)
									targetX = theMask.x + theMask.width/10;
								_time = Math.max(.1,Math.abs(targetX-container.x)/10000);
							}else if(container.width>theMask.width && targetX+container.width< theMask.x + theMask.width){
								targetX = theMask.x + theMask.width- container.width;
								_time = Math.max(.1,Math.abs(targetX-container.x)/10000);
							}
						}
						if(isVRoll)
							TweenLite.to(container,_time,{y:targetY,onUpdate:onUpdate,onComplete:backtoShow});
						else
							TweenLite.to(container,_time,{x:targetX,onUpdate:onUpdate,onComplete:backtoShow});
					}
					break;
			}

		}

		private var can_back:Boolean = true;

		public function set canback(b:Boolean):void
		{
			can_back = b;
		}

		private var timeoutId:uint;
		private function backtoShow():void
		{
			clearTimeout(timeoutId);
			if(isVRoll){
				if(container.y >theMask.y){
					TweenLite.to(container,.3,{y:theMask.y,onUpdate:onUpdate});
				}else if(container.height> theMask.height){
					if(container.y + container.height< theMask.y +theMask.height)
						TweenLite.to(container,.3,{y:theMask.y+theMask.height - container.height});
				}else{
					TweenLite.to(container,.3,{y:theMask.y,onUpdate:onUpdate});
				}
			}else{
				if(container.x >theMask.x){
					TweenLite.to(container,.3,{x:theMask.x,onUpdate:onUpdate});
				}else if(container.width > theMask.width){
					if(container.x + container.width  < theMask.x +theMask.width)
						TweenLite.to(container,.3,{x:theMask.x+theMask.width - container.width,onUpdate:onUpdate});
				}else{
					TweenLite.to(container,.3,{x:theMask.x,onUpdate:onUpdate});
				}
			}
		}

		public function set page(i:int):void
		{
			if(isVRoll){
				container.y = i*container.height/theMask.height;
			}else{
				container.x = i*container.width/theMask.width;
			}
			backtoShow();
		}

		public function nextPage():void
		{
			if(isVRoll){
				if(container.height> theMask.height){
					if(container.y < theMask.y )
						container.y += theMask.height;
				}
			}else{
				if(container.width> theMask.width){
					if(container.x < theMask.x )
						container.x += theMask.width;
				}
			}
			backtoShow();
		}


		public function prevPage():void
		{
			if(isVRoll){
				if(container.height> theMask.height){
					if(container.y + container.height- theMask.height> theMask.y )
						container.y -= theMask.height;
				}
			}else{
				if(container.width> theMask.width){
					if(container.x + container.width - theMask.width > theMask.x )
						container.x -= theMask.width;
				}
			}
			backtoShow();
		}


		private var mouY:int;
		private var mouX:int;
		private function clicked(e:Event):void
		{
			var target:Sprite = e.currentTarget as Sprite;
			if(target==null)
				return;
			switch(e.type){
				case MouseEvent.MOUSE_DOWN:
					mouY = container.y;
					mouX = container.x;
					break;
				case MouseEvent.MOUSE_UP:
					if(Math.abs(mouY -container.y)+ Math.abs(mouX - container.x)> 10)return;
					ClickObject = target;
					dispatchEvent(new Event(Event.SELECT));
					break;
			}

		}

		public function removes():void
		{
			container.y = theMask.y;
			ViewSet.removes(container);
		}
		public function resetPosition():void
		{
			container.y = theMask.y;
		}
		public var ClickObject:Sprite;

		public function get numItems():int
		{
			return container.numChildren-1;
		}
		public function getItemAt(i:int):DisplayObject
		{
			if(container.numChildren>i+1)
				return container.getChildAt(i+1);
			return null;
		}
		public function getItemByName(_name:String):DisplayObject
		{
			var i:int = 1;
			while(i<container.numChildren)
			{
				var child:DisplayObject = container.getChildAt(i);
				if(child.name==_name)
					return child;
				++i;
			}
			return null;
		}

		public function addItem(item:DisplayObject):DisplayObject
		{
			container.addChild(item);
			/*item.mouseChildren = false;*/
			/*item.buttonMode= true;*/
			item.addEventListener(MouseEvent.MOUSE_DOWN,clicked);
			item.addEventListener(MouseEvent.MOUSE_UP,clicked);

			backtoShow();
			initBg();
			return item;
		}

		public function initBg():void
		{
			if(container.contains(bg))container.removeChild(bg);
			/*bg.x = container.x;*/
			/*bg.y = container.y;*/
			bg.width = container.width;
			bg.height= container.height;
			container.addChildAt(bg,0).alpha=0;
		}
	}
}

